
    use: 'ie.ondevice.objectkit.utility.eventdispatcher.EventListener';

    EventDispatcher.implement
    (
        {
            /**
             * @private
             * An map of event types and listeners
             * @type {Object}
             */
            events: null
            
            /**
             * @private
             * The object that will become the target property of events
             * dispatched by this event dispatcher
             * @type {Object}
             */
        ,   target: null
            
            /**
             * @public
             * Add an event listener.
             * @param {String} type
             * @param {Function|EventListener} listener
             * @param {Object} [scope]
             * @return {void}
             */
        ,   addEventListener: function (type, listener, scope) 
            {
                if (false === EventListener.is(listener)) 
                {
                    listener= new EventListener(listener, scope);
                }
                
                if (false === this.willTrigger(type)) 
                {
                    this.events[type]= listener;
                    return;
                }
                
                this.removeEventListener(type, listener, scope);
                if (false === type in this.events) 
                {
                    this.events[type]= listener;
                    return;
                }
                
                this.events[type].unshift(listener)
                
            }
            
            /**
             * 
             * @param {String} type
             * @param {Function} method
             * @param {Object} scope
             */
        ,   findEventListener: function (type, method, scope) 
            {
                var result=
                    {
                        exists: false
                    ,   value: void(0)
                    }
                
                ,   listeners
                ,   listener
                ;
                
                if (false === type in this.events)
                    return result;
                    
                listeners= this.events[type];
                
                for (n= listeners.length; n; n--) 
                {
                    listener= listeners[i];
                    
                }        
                
            }    
            
            /**
             * 
             * @param {String} type
             * @param {Object|EventListener} listener
             * @param {Object} [scope]
             * @return {void}
             */
        ,   removeEventListener: function (type, listener, scope) 
            {
                if (0 === listeners.length)
                    delete this.events[type];
            }
            
            /**
             * Determine if this dispatcher will dispatch an event of a certain
             * type
             * @param {String} eventType
             * @return {void}
             */
        ,   willTrigger: function (eventType) 
            {
                return eventType in this.events;
            }
            
            /**
             * Dispatch an event. All listeners will be invoked.
             * @param {EventObject|String} eventObject
             * @param {Object} [attributes]
             * @return {void}
             */
        ,   dispatchEvent: function (eventObject, attributes) 
            {
                if (String.is(eventObject)) 
                {
                    eventObject= new EventObject(eventObject);
                }
                else if (false === EventObject.is(eventObject)) 
                {
                    throw new TypeError('EventObject or String expected');
                }
                
                var listeners= this.events[eventObject.type];
                if (null == listeners)
                    return;
                
                if (Object.is(attributes)) 
                {
                    for (var accessor in attributes) 
                    {
                        if (attributes.hasOwnProperty(accessor))
                            eventObject[accesor]= attributes[accessor];
                    }
                };
                
                eventObject.target= this.target;
                var n= listeners.length
                
                while (n--) 
                {
                    listeners[n].handleEvent(eventObject);
                }
            }
            
            /**
             * Dispose of an event dispatcher. All listeners will be removed.
             * @return {void}
             */
        ,   dispose: function () 
            {
                this.events= {};
            }
        }
    );
    
    /**
     * Create a new EventDispatcher
     * @param {Object} [target]
     * @constructor
     */
    function EventDispatcher (target) 
    {
        this.target= target || this;
    };
